package net.cocotea.sqltoy.lambda.factory.update;

import net.cocotea.sqltoy.lambda.factory.condition.AbstractLambdaCondition;
import net.cocotea.sqltoy.lambda.factory.condition.ICondition;
import net.cocotea.sqltoy.lambda.func.SFunction;
import net.cocotea.sqltoy.lambda.util.LambdaUtils;
import org.sagacity.sqltoy.model.EntityUpdate;

import java.util.Collection;
import java.util.function.Consumer;

/**
 * Lambda实体更新类
 * 
 * @param <T> 实体类型
 * @author CoCoTea
 * @since 0.0.3
 */
public class LambdaEntityUpdate<T> extends AbstractLambdaCondition<T> implements ILambdaEntityUpdate<T> {

    private static final long serialVersionUID = 7526248146566573283L;

    private Class<T> entityClass;
    private EntityUpdate entityUpdate;

    private LambdaEntityUpdate() {
        super();
    }

    public static <T> LambdaEntityUpdate<T> create(Class<T> clz) {
        return new LambdaEntityUpdate<T>().entityUpdate(EntityUpdate.create())
                .entityClass(clz);
    }

    protected LambdaEntityUpdate<T> entityUpdate(EntityUpdate entityUpdate) {
        this.entityUpdate = entityUpdate;
        return this;
    }

    protected LambdaEntityUpdate<T> entityClass(Class<T> clz) {
        this.entityClass = clz;
        return this;
    }

    public Class<T> entityClass() {
        return entityClass;
    }

    @Override
    public LambdaEntityUpdate<T> eq(SFunction<T, ?> col, Object value) {
        super.eq(col, value);
        return this;
    }

    @Override
    public LambdaEntityUpdate<T> neq(SFunction<T, ?> col, Object value) {
        super.neq(col, value);
        return this;
    }

    @Override
    public LambdaEntityUpdate<T> gt(SFunction<T, ?> col, Object value) {
        super.gt(col, value);
        return this;
    }

    @Override
    public LambdaEntityUpdate<T> gte(SFunction<T, ?> col, Object value) {
        super.gte(col, value);
        return this;
    }

    @Override
    public LambdaEntityUpdate<T> lt(SFunction<T, ?> col, Object value) {
        super.lt(col, value);
        return this;
    }

    @Override
    public LambdaEntityUpdate<T> lte(SFunction<T, ?> col, Object value) {
        super.lte(col, value);
        return this;
    }

    @Override
    public LambdaEntityUpdate<T> like(SFunction<T, ?> col, String value) {
        super.like(col, value);
        return this;
    }

    @Override
    public LambdaEntityUpdate<T> notLike(SFunction<T, ?> col, String value) {
        super.notLike(col, value);
        return this;
    }

    @Override
    public LambdaEntityUpdate<T> leftLike(SFunction<T, ?> col, String value) {
        super.leftLike(col, value);
        return this;
    }

    @Override
    public LambdaEntityUpdate<T> rightLike(SFunction<T, ?> col, String value) {
        super.rightLike(col, value);
        return this;
    }

    @Override
    public LambdaEntityUpdate<T> in(SFunction<T, ?> col, Collection<?> values) {
        super.in(col, values);
        return this;
    }

    @Override
    public LambdaEntityUpdate<T> notIn(SFunction<T, ?> col, Collection<?> values) {
        super.notIn(col, values);
        return this;
    }

    @Override
    public LambdaEntityUpdate<T> between(SFunction<T, ?> col, Object value1, Object value2) {
        super.between(col, value1, value2);
        return this;
    }

    @Override
    public LambdaEntityUpdate<T> and() {
        super.and();
        return this;
    }

    @Override
    public LambdaEntityUpdate<T> nested(Consumer<ICondition<T>> action) {
        super.nested(action);
        return this;
    }

    @Override
    public LambdaEntityUpdate<T> or() {
        super.or();
        return this;
    }

    @Override
    public String getFragment() {
        return super.getFragment();
    }

    @Override
    public EntityUpdate toEntityUpdate() {
        if (whereSql != null) {
            entityUpdate.where(whereSql.toString());
        }
        if (namesAndValuesMap != null) {
            entityUpdate.values(namesAndValuesMap);
        }
        return this.entityUpdate;
    }

    @Override
    public LambdaEntityUpdate<T> set(SFunction<T, Object> col, Object value) {
        String colName = LambdaUtils.getCol(col);
        this.entityUpdate.set(colName, value);
        return this;
    }

    @Override
    public LambdaEntityUpdate<T> where() {
        return this;
    }

}
